/**
 * 
 */
package sg.edu.nus.iss.vmcs.payment;

import java.awt.Frame;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import sg.edu.nus.iss.vmcs.customer.CustomerPanel;
import sg.edu.nus.iss.vmcs.payment.Payment.PaymentType;
import sg.edu.nus.iss.vmcs.system.MainController;
import sg.edu.nus.iss.vmcs.system.SimulatorControlPanel;
import sg.edu.nus.iss.vmcs.util.Log;

/**
 * @author moe
 * 
 */
public class PaymentController {
	private Payment.PaymentType payType = Payment.PaymentType.UNKNOWN;
	private HashMap<Payment.PaymentType, Payment> lsPayment = null;

	private IPaymentClient paymentClient = null;
	private MainController mainCtrl = null;
	private int totAmountReceived = 0;
	private int amountToCollect = 0;
	private int timeOut = 0;

	private PaymentPanel paymentPanel = null;

	public PaymentController(IPaymentClient paymentClient,
			MainController mainController) {
		lsPayment = new HashMap<Payment.PaymentType, Payment>();
		lsPayment.put(Payment.PaymentType.COIN_PAYTYPE, new CoinPayment(this,
				mainController));
		lsPayment.put(Payment.PaymentType.NETS_PAYTYPE, new NetsPayment(this,
				mainController));
		this.paymentClient = paymentClient;
		this.mainCtrl = mainController;
	}

	/**
	 * Start Receiving Payment
	 * 
	 * @param price
	 *            (in Cents)
	 * @param timeOut
	 *            (in Seconds)
	 */
	public void startPayment(int amountToCollect, int timeOut) {
		totAmountReceived = 0;
		this.amountToCollect = amountToCollect;
		this.timeOut = timeOut;
		this.restartPayment();
	}

	public void setPaymentType(Payment.PaymentType paymentType) {
		this.payType = paymentType;
	}

	/**
	 * Total amount Received
	 * 
	 * @param amountReceived
	 */
	public void processMoneyReceive(int amountReceived) {
		// totAmountReceived = amountReceived;
		// if (totAmountReceived >= amountToCollect) {
		paymentClient.processMoneyReceived(amountReceived);
		// }
	}

	public Boolean completePayment() {
		Payment p = lsPayment.get(this.payType);
		if (p != null) {
			p.completePayment(true);
		}
		amountToCollect = 0;

		return true;
	}

	public void refundPayment() {
		// for (Payment payment : lsPayment.values()) {
		// payment.completePayment(false);
		// }
		Payment p = lsPayment.get(this.payType);
		if (p != null) {
			p.completePayment(false);
		}
		amountToCollect = 0;
	}

	public CoinPayment getCoinPayment() {
		return (CoinPayment) lsPayment.get(Payment.PaymentType.COIN_PAYTYPE);
	}

	public NetsPayment getNetsPayment() {
		return (NetsPayment) lsPayment.get(Payment.PaymentType.NETS_PAYTYPE);
	}

	public void displayPaymentPanel() {
		paymentPanel = getPanel();
		paymentPanel.display();
		getCoinPayment().display();
		getNetsPayment().setActive(false);
	}

	public void refreshPaymentPanel() {
		getCoinPayment().display();
		getNetsPayment().setActive(false);
	}

	public PaymentPanel getPanel() {
		if (paymentPanel == null) {
			SimulatorControlPanel scp = mainCtrl.getSimulatorControlPanel();
			paymentPanel = new PaymentPanel((Frame) scp, this);
		}
		return paymentPanel;
	}

	public void closeDown() {
		getPanel().closeDown();
	}

	public void receivingPayment(Payment receiver) {
		Iterator<Entry<PaymentType, Payment>> iterator = lsPayment.entrySet()
				.iterator();

		while (iterator.hasNext()) {
			Entry<PaymentType, Payment> entry = iterator.next();
			if (entry.getValue().equals(receiver)) {
				setPaymentType(entry.getKey());
				Log.LogIt("PaymentController.receivingPayment:SetKey:"
						+ entry.getKey());
			} else {
				entry.getValue().setActive(false);
				Log.LogIt("PaymentController.receivingPayment:ReSetKey:"
						+ entry.getKey());
			}
		}

	}

	public void restartPayment() {
		for (Payment payment : lsPayment.values()) {
			payment.startPayment(this.amountToCollect, timeOut);
		}
		if (amountToCollect > 0) {
			getPanel().startPayment();
		} else {
			refreshPaymentPanel();
		}
	}
}
